import { _decorator, Component, Node, Vec3, Animation, Collider2D, Contact2DType } from 'cc';
import { Enemy } from './Enemy';
import { EnemyManager } from './EnemyManager';
import { SoundManager } from './SoundManager';
const { ccclass, property } = _decorator;

enum BULLET_TYPE {
    ARROW,
    BOMB
}

@ccclass('Bullet')
export class Bullet extends Component {
    // 基础属性
    @property
    private speed: number = 0;
    public damage: number = 10;
    private type: BULLET_TYPE = null;

    // 运动相关属性
    private isMoving: boolean = false;
    private target: Node = null;
    private direction: Vec3 = null;
    private time: number = 0;

    // 贝塞尔曲线相关
    private bezierT: number = 0;
    private readonly bezierDuration: number = 0.5;
    private startPos: number[] = [];
    private controlPos: number[] = [];
    private endPos: number[] = [];

    private soundManager:SoundManager = null;

    // 组件引用
    private animation: Animation = null;

    currentT: number = 0;

    private hasHit: boolean = false;


    collider: Collider2D = null;

    enemyManager:EnemyManager = null;
    enemies:Node[] = [];



    /**
     * 初始化子弹
     * @param target 目标节点
     * @param damage 伤害值
     * @param position 初始位置
     * @param type 子弹类型
     */
    public init(target: Node, damage: number, position: Vec3, type: BULLET_TYPE) {
        this.target = target;
        this.damage = damage;
        this.node.worldPosition = position;
        this.isMoving = true;
        this.bezierT = 0;
        this.type = type;

        this.animation = this.node.getComponent(Animation);

        // 设置贝塞尔曲线的三个点
        const startPos = this.node.worldPosition;
        const endPos = this.target.worldPosition;

        // 计算中间控制点（抛物线最高点）
        const distance = Vec3.distance(startPos, endPos);
        const midPoint = new Vec3(
            (startPos.x + endPos.x) / 2,
            Math.max(startPos.y, endPos.y) + distance * 0.5, // 高度为距离的一半
            (startPos.z + endPos.z) / 2
        );

        // 保存三个控制点
        this.startPos = [startPos.x, startPos.y];
        this.controlPos = [midPoint.x, midPoint.y];
        this.endPos = [endPos.x, endPos.y];
    }

    start() {
        this.soundManager = SoundManager.instance;
        this.enemyManager = EnemyManager.getInstance();
        this.collider = this.node.getComponent(Collider2D);
        //设置碰撞器
        this.collider.on(Contact2DType.BEGIN_CONTACT, this.onContactEnter, this);
        this.collider.on(Contact2DType.END_CONTACT, this.onContactEnd, this);
    }


    onContactEnter(selfCollider: Collider2D, otherCollider: Collider2D) {
        if (this.hasHit) {
            return;
        }

        switch (this.type) {
            case BULLET_TYPE.ARROW:
                otherCollider.node.getComponent(Enemy).takeDamage(this.damage);
                break;

            case BULLET_TYPE.BOMB:
                console.log("炸弹爆炸");
                this.explode();
                break;
        }

        this.hasHit = true;
    }

    onContactEnd() {

    }

    /**
     * 更新子弹位置和状态
     * @param deltaTime 帧间隔时间
     */
    update(deltaTime: number) {

        // 如果是炸弹类型且正在播放爆炸动画，继续播放
        if (this.type === BULLET_TYPE.BOMB &&
            this.animation?.getState("explosion")?.isPlaying) {
            return;
        }

        if(!this.isMoving){
            return;
        }

        // 如果子弹已经无效，直接销毁
        if (!this.isMoving || !this.target || !this.target.isValid) {
            this.node.destroy();
            return;
        }

        // 更新贝塞尔曲线的时间参数
        this.bezierT += deltaTime / this.bezierDuration;
        if (this.bezierT > 1) this.bezierT = 1;

        // 计算当前位置
        const t = this.bezierT;
        const currentX = (1 - t) * (1 - t) * this.startPos[0] + 2 * (1 - t) * t * this.controlPos[0] + t * t * this.endPos[0];
        const currentY = (1 - t) * (1 - t) * this.startPos[1] + 2 * (1 - t) * t * this.controlPos[1] + t * t * this.endPos[1];

        // 更新位置
        this.node.worldPosition = new Vec3(currentX, currentY, 0);

        // 计算朝向
        if (this.bezierT < 1) {
            // 计算下一帧的位置来确定方向
            const nextT = Math.min(t + 0.1, 1);
            const nextX = (1 - nextT) * (1 - nextT) * this.startPos[0] + 2 * (1 - nextT) * nextT * this.controlPos[0] + nextT * nextT * this.endPos[0];
            const nextY = (1 - nextT) * (1 - nextT) * this.startPos[1] + 2 * (1 - nextT) * nextT * this.controlPos[1] + nextT * nextT * this.endPos[1];


            const angle = Math.atan2(nextY - currentY, nextX - currentX);
            this.node.angle = (angle * 180 / Math.PI) + 180;
        }

        // 检查是否击中目标
        if (this.bezierT >= 1) {
            this.onHitTarget();
            return;
        }

        // 检查是否提前击中目标（距离检测）
        const targetPos = this.target.worldPosition;
        const currentPos = this.node.worldPosition;
        if (Vec3.distance(currentPos, targetPos) < 5) {
            this.onHitTarget();
        }
    }

    /**
     * 处理子弹击中目标的逻辑
     * @private
     */
    private onHitTarget() {
        if (!this.node || !this.node.isValid) {
            return;
        }

        this.isMoving = false;  // 停止移动

        //子弹打到不同敌人的不同效果
        switch (this.type) {

            //炸弹塔子弹
            case BULLET_TYPE.BOMB:
                this.soundManager.playBombHitAudio();
                this.animation.on(Animation.EventType.FINISHED, () => {
                    if (this.node && this.node.isValid) {
                        this.node.destroy();
                    }
                }, this);

                this.animation.play("explosion");
                break;

            //箭塔子弹
            case BULLET_TYPE.ARROW  :
                this.soundManager.playArrowHitAudio();
                this.node.destroy();
                break;
        }

    }


    //群体伤害
    explode(){

        //获取敌人列表
        this.enemies = this.enemyManager.enemies;

        if(this.enemies.length == 0){
            return;
        }

        for(var i = 0;i < this.enemies.length;i++){
            var enemy = this.enemies[i].getComponent(Enemy);
            var distance = Vec3.distance(this.node.worldPosition,this.enemies[i].worldPosition);
            
            console.log("距离"+distance);
            if(distance < 100){
                enemy.takeDamage(this.damage);
            }
        }
    }
}


